#include "stdafx.h"

extern CCamShiftHelper g_camshiftHelper;

extern cWglARTK g_wglARTK;
extern cPMDModel	g_clPMDModel;
extern cVMDMotion	g_DanceMotion;
extern CGlobe		g_global;
extern HWND		g_hWnd;
extern cVMDMotion g_RunMotion;
extern CTextToRead g_textToRead;
extern cVMDMotion	g_RegretMotion;


float getElapsedFrame( void )
{
	static int	s_iPrevTime = 0;
	int			iTime = glutGet( GLUT_ELAPSED_TIME );
	float		fDiffTime;

	if( s_iPrevTime == 0 )	s_iPrevTime = iTime;
	fDiffTime = (float)(iTime - s_iPrevTime) * (30.0f / 1000.0f);

	s_iPrevTime = iTime;

	return fDiffTime;
}

unsigned __stdcall threadAR(void * p)
{
	// wait 
	WaitForSingleObject(g_global.hThreadOK, INFINITE);

	g_camshiftHelper._OpenAdjustWindow();

	while(1)
	{

		if ( g_wglARTK.update() )
		{
			Vector3	vecCamPos;
			g_wglARTK.getCameraPos( &vecCamPos );

			float		fElapsedFrame = getElapsedFrame();

			if( fElapsedFrame > 10.0f )	fElapsedFrame = 10.0f;

			g_clPMDModel.updateMotion( fElapsedFrame );
			g_clPMDModel.updateNeckBone( &vecCamPos );
			g_clPMDModel.updateSkinning();

			// ----------------------
			// by aicro

			char * dataImage = NULL;
			g_wglARTK.getImageData(&dataImage);

			if (dataImage != NULL)
			{
				// try camshift
				g_camshiftHelper._Fill_CV_IplImage(g_global.imgWidth, g_global.imgHeight, (char*)dataImage);

				// call the camshift to get the position and angle of the 2Dbox
				g_camshiftHelper._ShowAdjustWindow(true);

				// here we take the center of the picture
				int x, y;
				g_camshiftHelper._GetDetectedCenter(&x, &y);
				//printf("x = %3d, y = %3d\n", x, y);

				// use opengl to get the inverse points in the world coordinates
				// base on the original image sizes to test crash
				GLint viewport[4];
				viewport[0] = viewport[1] = 0;
				viewport[2] = g_global.imgWidth;
				viewport[3] = g_global.imgHeight;


				GLdouble mvmatrix[16];
				//glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
				g_wglARTK.getModelViewMat(mvmatrix);

				GLdouble projmatrix[16];
				//glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
				g_wglARTK.getProjectionMat(projmatrix);

				GLint realy = viewport[3] - (GLint)y;

				gluUnProject((GLdouble)x, (GLdouble)realy, 1.0,\
					mvmatrix, projmatrix, viewport, \
					&(g_global.wxDir), &(g_global.wyDir), &(g_global.wzDir) );

				gluUnProject((GLdouble)g_global.imgWidth/2, \
					(GLdouble)g_global.imgHeight/2, \
					0.0, mvmatrix, projmatrix, viewport, \
					&(g_global.wxOri), &(g_global.wyOri), &(g_global.wzOri) );


				// ----------------------
				// by aicro
				// test crash
				if (!( x == 0 || y == 0 
					 || g_global.wxOri == 0 || g_global.wyOri == 0 || g_global.wzOri == 0
					 || g_global.wxDir == 0 || g_global.wyDir == 0 || g_global.wzDir == 0) )
				{
					// we have prepared well
					CCrashTest crashTest;

					// we should change the coordinates because of the size and location 
					// of the change of virtual character

					crashTest.calculateAABB(-5*g_global.fScale, 0, -5*g_global.fScale,\
											5*g_global.fScale, 25*g_global.fScale, 5*g_global.fScale);

					double t = crashTest.rayIntersect(g_global.wxOri, g_global.wyOri, g_global.wzOri,\
						g_global.wxDir, g_global.wyDir, g_global.wzDir);

					static int count = 0;
					if (t != -1)
					{						
						printf("TOUCH!!!	%3d\n", count++);
						if (g_global.bTouch == false)
						{
							// load motion
							g_clPMDModel.setMotion( &g_RunMotion, true );
							g_global.bNormalChanged = true;
						}
						
						//PlaySound(L"..\\data\\taoyan.wav", NULL, SND_FILENAME|SND_ASYNC);

						// we have touch it
						g_global.bTouch = true;

					}
					else
					{
						g_global.bTouch = false;
						if (g_global.bNormalChanged == true)
						{
							g_global.bNormalChanged = false;

							if (g_global.bDance == true)
							{
								g_clPMDModel.setMotion(&g_DanceMotion, true);
							}
							else
							{
								g_clPMDModel.setMotion(&g_RegretMotion, true);
							}
						}
					}
				}
			}



			InvalidateRect(g_hWnd, NULL, TRUE);

		}

		if (g_global.bStop)
		{
			SetEvent(g_global.hStop);
			break;
		}
	}

	g_camshiftHelper._CloseAdjustWindow();

	return 0;
}